package com.hanxiaozhang.no3algorithm;

import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 * <p>
 * 第一题：编写程序计算过10个正整数平均值，找出10个数中与平均值距离（差值的绝对值）最近的三个数，
 * 以距离大小对这三个数进行排序输出。
 * <p>
 * 示例
 * 输入[33,44,61,2,36,42,56,81,11,17]
 * 返回[36,42,33]
 *
 * @author hanxinghua
 * @create 2022/7/3
 * @since 1.0.0
 */
public class No5ArrayAvgThree {

    public static void main(String[] args) {

        Integer[] nums = {33, 44, 61, 2, 36, 42, 56, 81, 11, 17};
        System.out.println(Arrays.toString(find1(nums)));

    }


    public static Integer[] find(Integer[] nums) {

        int len = nums.length, sum = 0;

        for (int i = 0; i < len; i++) {
            sum += nums[i];
        }

        double avg = sum / len;

        for (int i = 1; i < len; i++) {
            for (int j = 0; j < len - 1; j++) {
                if (nums[j] > nums[j + 1]) {
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }

        double min = nums[len - 1];
        int index = 0;
        for (int i = 0; i < len; i++) {
            double sub = Math.abs(avg - nums[i]);

            if (min > sub) {
                min = sub;
                index = i;
            }
        }

        Integer[] targets = new Integer[3];
        targets[0] = nums[index - 1];
        targets[1] = nums[index];
        targets[2] = nums[index + 1];


        return targets;
    }

    public static Integer[] find1(Integer[] nums) {

        int len = nums.length, sum = 0;

        for (int i = 0; i < len; i++) {
            sum += nums[i];
        }

        double avg = sum / len;
        Map<Double, Integer> map = new TreeMap<>();
        for (int i = 0; i < len; i++) {
            map.put(Math.abs(avg - nums[i]), nums[i]);
        }

        Integer[] targets = new Integer[3];
        int count = 0;
        for (Map.Entry<Double, Integer> entry : map.entrySet()) {
            if (count <= 2) {
                targets[count++] = entry.getValue();
            } else {
                break;
            }
        }
        return targets;
    }

    public static Integer[] find2(Integer[] nums) {

        double avg = Arrays.stream(nums)
                .collect(Collectors.averagingDouble(x -> x));
        Map<Double, Integer> map = new TreeMap<>();
        Arrays.stream(nums).forEach(x -> {
            map.put(Math.abs(avg - x), x);
        });
        Integer[] targets = new Integer[3];
        int count = 0;
        for (Map.Entry<Double, Integer> entry : map.entrySet()) {
            if (count <= 2) {
                targets[count++] = entry.getValue();
            } else {
                break;
            }
        }
        return targets;
    }


}
